package main

import (
	"distributed-task-scheduler/crontab/worker"
	"flag"
	"fmt"
	"runtime"
	"time"
)

// golang是一个多线程的执行，开发时使用的是协程，协程会被调度到线程上，线程是由操作系统来给
// golang要发挥操作系统的多核特性，就要让线程数量和CPU的核数量相等

var (
	configFile string // 配置文件路径
)

// 解析命令行参数
func initArgs() {
	// worker -config ./worker.json -xxx 123 -yyy ddd
	// worker -h
	flag.StringVar(&configFile, "config", "./worker.json", "worker.json") // 字符串的命令行参数

	// 解析所有的命令行参数到指定的变量中
	flag.Parse()
}

// 初始化线程数量：配置golang的线程数量
func initEnv() {
	runtime.GOMAXPROCS(runtime.NumCPU()) // NumCPU()会返回CPU的核心数量
}

func main() {
	var (
		err error
	)
	// 初始化命令行参数
	initArgs()

	// 初始化线程
	initEnv()

	// 加载配置
	if err = worker.InitConfig(configFile); err != nil {
		goto ERR
	}

	// 服务注册
	if err = worker.InitRegister(); err != nil {
		goto ERR
	}

	// 启动日志协程
	if err = worker.InitLogSink(); err != nil {
		goto ERR
	}

	// 启动执行器
	if err = worker.InitExecutor(); err != nil {
		goto ERR
	}

	// 启动任务调度器
	if err = worker.InitScheduler(); err != nil {
		goto ERR
	}

	// 初始化任务管理器
	if err = worker.InitJobMgr(); err != nil {
		goto ERR
	}

	// 正常退出
	// HTTP服务是在协程中运行的，主协程退出HTTP服务也会退出，for循环阻止主函数退出，服务就可以常驻了
	for {
		time.Sleep(1 * time.Second)
	}
	return

ERR: // 异常退出 命令行启动服务，出错也能在命令行看到出错原因
	fmt.Println(err)
}

// Goland里面的`./`表示gopath的目录下的文件，不使用默认的就需要配置Configuration，里面的运行目录需要修改为指定程序运行的目录
